package com.code.ape.codeape.device.quartz;

import cn.hutool.core.collection.CollectionUtil;
import com.code.ape.codeape.admin.api.entity.SysHospital;
import com.code.ape.codeape.admin.api.feign.RemoteSysHospitalService;
import com.code.ape.codeape.common.core.util.R;
import com.code.ape.codeape.common.core.util.RetOps;
import com.code.ape.codeape.device.config.QuartzTaskExecutorConfig;
import com.code.ape.codeape.device.service.QcCountService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * @author 公众号：码猿技术专栏
 * @url: www.java-family.cn
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class QcRecordQuartz {

	private final QcCountService qcCountService;


	private final RemoteSysHospitalService remoteSysHospitalService;

	@Resource(name = QuartzTaskExecutorConfig.QUARTZ_THREAD_POOL_NAME)
	private Executor executor;

	/**
	 * 质控统计功能实现，每天统计一次
	 */
	@XxlJob("qcCountJobHandler")
	public void qcCount() {
		XxlJobHelper.log("质控统计功能开始执行.........");
		//查询所有的医院
		R<List<SysHospital>> hospitalRes = remoteSysHospitalService.getAllSysHospital();
		List<SysHospital> hospitalList = RetOps.of(hospitalRes).getData().orElse(new ArrayList<>());
		if (CollectionUtil.isEmpty(hospitalList))
			return;
		//分组，分为4组任务并行
		//分组的数量
		int total= Math.min(hospitalList.size(), 4);
		//每组的数量
		int num=hospitalList.size()%total==0?hospitalList.size()/total:hospitalList.size()/total+1;
		List<CompletableFuture<Void>> futures=new ArrayList<>();
		for (int i = 0; i < 4; i++) {
			List<Long> ids = hospitalList.stream().skip(i * num).limit(num).map(SysHospital::getId).collect(Collectors.toList());
			CompletableFuture<Void> future = CompletableFuture.runAsync(() -> this.doExecute(ids), executor);
			futures.add(future);
		}
		CompletableFuture.allOf((futures.toArray(new CompletableFuture<?>[0]))).join();
		XxlJobHelper.log("质控统计功能结束执行.........");
	}

	private void doExecute(List<Long> hosIds){
		for (Long hosId : hosIds) {
			qcCountService.executeJob(hosId);
		}
	}
}
